package com.itheima.health.filter;

import com.alibaba.fastjson.JSON;
import com.itheima.health.entity.Result;
import com.itheima.health.pojo.Permission;
import com.itheima.health.pojo.Role;
import com.itheima.health.pojo.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@Slf4j
@WebFilter(urlPatterns = "/*")
public class UserFilter implements Filter {
    //可以直接访问的URI
    private String[] urlArr = new String[]{
            "/user/login",
            "/user/logout",
            "/common/**",
            "/mobile/validateCode/**",
            "/mobile/login/**",
    };
    //需要授权访问的url
    private Map<String, String> permissionUrlMap = new HashMap<>();

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 读取资源需要的权限
        putMap();
    }

    private void putMap() {
        permissionUrlMap.put("/checkitem/delete", "CHECKITEM_DELETE");
        permissionUrlMap.put("/checkgroup/delete", "CHECKGROUP_DELETE");
        permissionUrlMap.put("/setmeal/delete", "SETMEAL_DELETE");
        permissionUrlMap.put("/report/**", "REPORT_VIEW");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //强转
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        //获取请求的URL
        String requestURI = request.getRequestURI();
        //打印
        log.info("[登录检查过滤器-拦截请求:{}]",requestURI);
        //判断
        boolean isAuth = checkAuthUrl(requestURI);
        if (isAuth) {
            filterChain.doFilter(request, response);
            return;
        }
        //获取当前用户信息 判断是否登录
        User user = (User) request.getSession().getAttribute("user");
        if (user != null) {
            log.info("[登录检查过滤器-已登录放行 id:{}]",user.getUsername());
            //判断当前用户权限
            boolean flag = checkLoginAuthUr(requestURI, user);
            if (flag) {
                filterChain.doFilter(request, response);
            } else {
                //已登陆但是没有访问权限
                response.setContentType("application/json; charset=UTF-8");
                response.getWriter().write(JSON.toJSONString(new Result(false, "权限不匹配！")));
            }

        } else if (request.getSession().getAttribute("member") != null) {
            // 移动端登陆检查
            filterChain.doFilter(request, response);
        } else {
            // 未登录  返回错误信息
            response.setContentType("application/json; charset=UTF-8");
            response.getWriter().write(JSON.toJSONString(new Result(false, "请前往登录")));
        }
    }

    //判断需要放行的url
    private boolean checkAuthUrl(String requestURI) {
        //路径匹配
        final AntPathMatcher pathMatcher = new AntPathMatcher();

        for (String url : urlArr) {
            if (pathMatcher.match(url, requestURI)) {
                log.info("[登录检查过滤器],匹配放行的url:{}",url);
                return true;
            }
        }
        return false;
    }

    //判断权限
    private boolean checkLoginAuthUr(String reqUrl, User user) {
        //路径匹配
        final AntPathMatcher pathMatcher = new AntPathMatcher();
        //先判断访问路径
        Set<String> keySet = permissionUrlMap.keySet();
        String currKeyUrl = null;
        for (String urlKey : keySet) {
            //当前请求的地址和模拟的权限map集合对比
            if (pathMatcher.match(urlKey, reqUrl)) {
                currKeyUrl = urlKey;
            }
        }
        if (currKeyUrl == null) {
            //说明当前访问的地址不需要授权就可以访问
            log.info("[登录检查过滤器-当前URL无需权限]，reqUrl:{}", reqUrl);
            return true;
        }
        //执行到这里说明 当前访问的的url需要权限
        String authKeyword = permissionUrlMap.get(currKeyUrl);
        log.info("[登录检查过滤器-当前URL需要权限]currKeyUrl:{},keyWord:{}",currKeyUrl,authKeyword);
        //获取当前用户的角色及权限
        Set<Role> userRoles = user.getRoles();
        log.info("[登录检查过滤器-当前用户权限信息]userRoles:{}",userRoles);
        for (Role userRole : userRoles) {
            Set<Permission> permissions = userRole.getPermissions();
            for (Permission permission : permissions) {
                if (permission.getKeyword().equals(authKeyword)) {
                    //执行到这里说明用户权限匹配 可以操作
                    log.info("[登录检查过滤器-权限通过]");
                    return true;
                }
            }
        }
        log.info("[登录检查过滤器-权限不匹配]");
        return false;
    }

    @Override
    public void destroy() {

    }
}
